﻿using System;
using System.Collections.Generic;
using System.Linq;
using DLM.Domain.Model;
using DLM.Domain.Repositories;
using DLM.Infrastructure.UnitOfWork;
using DLM.Infrastructure.Domain;
using DLM.Domain.DTO;
using Webdiyer.WebControls.Mvc;

namespace DLM.Data.EF.CodeFirst.Repositories
{
    public class FriendRepository : Repository<Friend, int>, IFriendRepository
    {
        public FriendRepository(IUnitOfWork unitOfWork)
            : base(unitOfWork)
        {

        }

        public override IEnumerable<Friend> FindAll(System.Linq.Expressions.Expression<Func<Friend, bool>> query, int index, int count)
        {
            if (index < 0 || count < 0)
            {
                throw new ArgumentOutOfRangeException("Index or count cannot be negative!");
            }

            return this.ActiveContext.Friend.Where(query)
                .OrderByDescending(f => f.CreateDate)
                .ToPagedList<Friend>(index, count);
        }

        public new System.Collections.IEnumerator GetEnumerator()
        {
            throw new NotImplementedException();
        }


        public IEnumerable<Domain.DTO.FriendDTO> FindFriendDTO(string accountName, int pageIndex, int pageSize)
        {
            if (string.IsNullOrEmpty(accountName))
            {
                throw new ArgumentNullException("Account name");
            }
            var result = from u in this.ActiveContext.User
                         join f in this.ActiveContext.Friend
                         on u.UserID equals f.UserID
                         join d in this.ActiveContext.User
                         on f.MyFriendID equals d.UserID
                         where u.AccountName == accountName
                         select new FriendDTO
                         {
                             CreateDate = f.CreateDate,
                             FriednPhoto = d.Photo,
                             FriendID = f.FriendID,
                             FriendAccount = d.AccountName,
                             FriendName = d.Name,
                             IsConfirmed = f.IsConfirmed,
                             MyFriendID = f.MyFriendID,
                             UserID = f.UserID
                         };
            return result.OrderByDescending(f => f.CreateDate).ToPagedList(pageIndex, pageSize);
        }


        public IEnumerable<FriendDTO> FindMyFriend(string accountName, int pageIndex, int pageSize)
        {
            if (string.IsNullOrEmpty(accountName))
            {
                throw new ArgumentNullException("Account name");
            }
            //var result = from u in this.ActiveContext.User
            //             join f in this.ActiveContext.Friend
            //             on u.UserID equals f.UserID
            //             where u.AccountName == accountName &&
            //             f.IsConfirmed == true
            //             select new FriendDTO
            //             {
            //                 CreateDate = f.CreateDate,
            //                 FriednPhoto = u.Photo,
            //                 FriendID = f.FriendID,
            //                 FriendAccount = u.AccountName,
            //                 FriendName = u.Name,
            //                 IsConfirmed = f.IsConfirmed,
            //                 MyFriendID = f.MyFriendID,
            //                 UserID = f.UserID
            //             };

            var list = from u in this.ActiveContext.User
                       join f in this.ActiveContext.Friend
                       on u.UserID equals f.UserID
                       join d in this.ActiveContext.User
                       on f.MyFriendID equals d.UserID
                       where u.AccountName == accountName && f.IsConfirmed == true
                       select new FriendDTO 
                       {
                           CreateDate = f.CreateDate,
                           FriednPhoto = d.Photo,
                           FriendID = f.FriendID,
                           FriendAccount = d.AccountName,
                           FriendName = d.Name,
                           IsConfirmed = f.IsConfirmed,
                           MyFriendID = f.MyFriendID,
                           UserID = f.UserID
                       };
            return list.OrderByDescending(f => f.CreateDate).ToPagedList(pageIndex, pageSize);
        }

        public IEnumerable<FriendDTO> FindFriednRequest(string accountName, int pageIndex, int pageSize)
        {
            if (string.IsNullOrEmpty(accountName))
            {
                throw new ArgumentNullException("Account name");
            }
            var result = from u in this.ActiveContext.User
                         join f in this.ActiveContext.Friend
                         on u.UserID equals f.MyFriendID
                         join d in this.ActiveContext.User
                         on f.UserID equals d.UserID
                         where u.AccountName == accountName &&
                         f.IsConfirmed == false
                         
                         select new FriendDTO
                         {
                             CreateDate = f.CreateDate,
                             FriednPhoto = d.Photo,
                             FriendID = f.FriendID,
                             FriendAccount = d.AccountName,
                             FriendName = d.Name,
                             IsConfirmed = f.IsConfirmed,
                             MyFriendID = f.MyFriendID,
                             UserID = f.UserID
                         };
            //this.ActiveContext.Database
            //    .SqlQuery<FriendDTO>("select distinct f.friendid,f.userid,f.myfriendid,d.accountname,d.name,d.photo,f.createdate,f.isconfirmed from friend f join [user] u on f.userid=u.userid join [user] d on d.userid=f.myfriendid where u.accountname='{0}' and f.isconfirmed = 0", accountName);
            return result.OrderByDescending(f => f.CreateDate).ToPagedList(pageIndex, pageSize);
        }

        public int FindFriendRequestCount(string accountName)
        {
            if (string.IsNullOrEmpty(accountName))
            {
                throw new ArgumentNullException("Account name");
            }
            var result = from u in this.ActiveContext.User
                         join f in this.ActiveContext.Friend
                         on u.UserID equals f.MyFriendID
                         where u.AccountName == accountName &&
                         f.IsConfirmed == false
                         select f;

            return result.Count();
        }
    }
}
